package com.lagou.sqlsession;

import com.lagou.config.Configuration;
import com.lagou.mapping.MappedStatement;

import java.lang.reflect.*;
import java.util.List;

public class DefaultSqlSession implements SqlSession {
    private Configuration configuration;

    public DefaultSqlSession(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <E> List<E> selectList(String statementId, Object... param) throws Exception {
        System.out.println("selectList:"+statementId+param);
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        Executor executor = new SimpleExecutor(configuration);
        return executor.query(mappedStatement,param);
    }

    @Override
    public <E> E selectOne(String statementId, Object... param) throws Exception {
        System.out.println("selectOne:"+statementId+param);
        List<E> list = selectList(statementId, param);
        if (list == null || list.isEmpty()){
            return null;
        }
        return list.get(0);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<T> tClass) {
        Object proxyInstance =  Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{tClass},
                (proxy, method, args) -> {
            //约定 statementId = mapper接口类的全名.方法名
            String methodName = method.getName();
            String className = method.getDeclaringClass().getName();
            String statementId = className +"." + methodName;

            Type genericReturnType = method.getGenericReturnType();
            MappedStatement statement = configuration.getMappedStatementMap().get(statementId);
            if (statement == null){
                throw new RuntimeException("mapper未找到映射配置");
            }
            String sqlType = statement.getSqlType();
            if ("select".equals(sqlType)){
                //查询语句
                if (genericReturnType instanceof ParameterizedType){
                    return selectList(statementId,args);
                }

                return selectOne(statementId,args);
            }else if ("update".equals(sqlType)){
                return update(statementId,args);
            }else if ("delete".equals(sqlType)){
                return delete(statementId,args);
            }else if ("insert".equals(sqlType)) {
                return insert(statementId, args);
            }
            throw new RuntimeException("未知的sql类型");
        });

        return (T) proxyInstance;
    }

    @Override
    public int insert(String statementId, Object... args) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        Executor executor = new SimpleExecutor(configuration);
        return executor.update(mappedStatement,args);
    }

    @Override
    public int update(String statementId, Object... args) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        Executor executor = new SimpleExecutor(configuration);
        return executor.update(mappedStatement,args);
    }

    @Override
    public int delete(String statementId, Object... args) throws Exception {
        MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
        Executor executor = new SimpleExecutor(configuration);
        return executor.update(mappedStatement,args);
    }
}
